package ivia.fiuza.days.classes;

import ivia.fiuza.days.interfaces.Meses;
import ivia.fiuza.days.interfaces.DiasDaSemana;

public class PrimeiroDiaDaSemana {

	// Dias 1º dos meses do ano 1
	private static final int[]	diasPrimeiroDoPrimeiroAno	= {	-1,
																DiasDaSemana.SEGUNDA_FEIRA,	// Janeiro
																DiasDaSemana.QUINTA_FEIRA,	// Fevereiro
																DiasDaSemana.QUINTA_FEIRA,	// Março
																DiasDaSemana.DOMINGO,		// Abril
																DiasDaSemana.TERCA_FEIRA,	// Maio
																DiasDaSemana.SEXTA_FEIRA,	// Junho
																DiasDaSemana.DOMINGO,		// Julho
																DiasDaSemana.QUARTA_FEIRA,	// Agosto
																DiasDaSemana.SABADO,		// Setembro
																DiasDaSemana.SEGUNDA_FEIRA,	// Outubro
																DiasDaSemana.QUINTA_FEIRA,	// Novembro
																DiasDaSemana.SABADO };		// Dezembro

	private static final String[]	semana					= { "Domingo",
																"Segunda-feira",
																"Terça-feira",
																"Quarta-feira",
																"Quinta-feira",
																"Sexta-feira",
																"Sábado" };

	// Retorna o dia da semana do primeiro dia do mês, no referido ano.
	public static String primeiroDiaDaSemana( int mes, int ano ) {
		boolean casoEspecial	= Ano.forBissexto( ano ) && mes < Meses.MARCO;
		int		diaInicial		= casoEspecial ?	recuarDiaDaSemana( PrimeiroDiaDaSemana.diasPrimeiroDoPrimeiroAno[ mes ], 2 ) :
													recuarDiaDaSemana( PrimeiroDiaDaSemana.diasPrimeiroDoPrimeiroAno[ mes ], 1 ),
				incrementos		= PrimeiroDiaDaSemana.calcularIncrementos(	ano );
		return PrimeiroDiaDaSemana.semana[ avancarDiaDaSemana( diaInicial, incrementos ) ];
	}

	/*
	 *  Calcula a quantidade de incrementos a serem feitos desde o primeiro ano, até o ano passado como parâmetro.
	 */
	public static int calcularIncrementos( int ano ){
		int	anosBissextos		= 0,
			incrementosSimples	= 0;
	
		anosBissextos		= PrimeiroDiaDaSemana.contarAnosBissextosAte( ano );
		incrementosSimples	= ano - anosBissextos;

		// Para cada ano bissexto, são feitos dois incrementos ao mesmo tempo
		return ( ( anosBissextos * 2 ) + incrementosSimples );
	}

	/*
	 * Incrementa o dia da semana, passado em diaAtual, um número de vezes igual a quantidadeDeIncrementos.
	 * O resultado do incremento e o dia atual, devem ser um valor entre 0 e 6.
	 * Retorna um valor posterior ou anterior ao diaAtual, dentro da semana.
	 */
	public static int avancarDiaDaSemana( int diaAtual, int quantidadeDeIncrementos ){
		for( int contador = 0; contador < quantidadeDeIncrementos; contador++ ){
			diaAtual++;
			if( diaAtual > 6 ){
				diaAtual = 0;
			}
		}
		return diaAtual;
	}

	/*
	 * Oposto do método avancarDiaDaSemana().
	 */
	public static int recuarDiaDaSemana( int diaAtual, int decrementos ){
		for( int counter = 0; counter < decrementos; counter++ ){
			diaAtual--;
			if( diaAtual < 0 ){
				diaAtual = 6;
			}
		}
		return diaAtual;
	}

	// Retorna uma string com o nome do dia da semana.
	public static String getDiaDaSemana( int indiceDoDiaDaSemana ){
		return semana[ indiceDoDiaDaSemana ];
	}

	// Conta quantos anos bissextos se passaram até chegar no ano passado como parâmetro
	public static int contarAnosBissextosAte( int ano ){
		int anosBissextos = 0;
		for( int anoAtual = 1; anoAtual <= ano; anoAtual++ ){
			if( Ano.forBissexto( anoAtual ) ){
				anosBissextos++;
			}
		}
		return anosBissextos;
	}
}
